﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.TeamFoundation.WorkItemTracking.Client;

namespace WIAssistant
{
    public static class PadWorks
    {
        public static void AddWorkItemToPad(this Dictionary<WorkItem, Canvas> pad, WorkItem item, IMain form)
        {
            if (!pad.ContainsKey(item))
            {
                WorkItemTypeToColorConverter converter = new WorkItemTypeToColorConverter();
                Brush background = (Brush)converter.Convert(item.Type, null, null, null);
                string defaultTitle = item.GetDefaultColumnValue().ToString();
                var canvas = NewPadItem(item.Id.ToString(), defaultTitle, background);
                pad.Add(item, canvas);
                form.AddCanvasToPad(canvas);

                OnAddItemToPad(item);
            }
        }

        private static void OnAddItemToPad(WorkItem item)
        {
            // Check to see if we have added a new type
            if (MainMediator.Instance.ShowMoveTypes == Visibility.Visible)
            {
                MainMediator.AddMappingForWorkItem(item);
            }
        }


        // Resend all the items in the pad back to the form
        public static void RefreshCanvasPad(this Dictionary<WorkItem, Canvas> pad, IMain form)
        {
            foreach (KeyValuePair<WorkItem, Canvas> workItemAndCanvas in pad)
            {
                form.AddCanvasToPad(workItemAndCanvas.Value);
            }
        }

        // Overload to allow calling with just the ID
        public static void RemoveWorkItemFromPad(this Dictionary<WorkItem, Canvas> pad, int workItemID, IMain form)
        {
            WorkItem workItem;
            try
            {
                workItem = pad.Keys.Where(x => x.Id == workItemID).Single();
            }
            catch (InvalidOperationException exception)
            {
                if (exception.Message == "Sequence contains no elements")
                    return;
                else
                    throw;
            }

            pad.RemoveWorkItemFromPad(workItem, form);
        }

        // Remove the item from the pad
        public static void RemoveWorkItemFromPad(this Dictionary<WorkItem, Canvas> pad, WorkItem item, IMain form)
        {
            Canvas canvas;
            pad.TryGetValue(item, out canvas);
            form.RemoveCanvasFromPad(canvas);
            pad.Remove(item);
        }


        private static Canvas NewPadItem(string title, string desc, Brush background)
        {
            const int width = 200;
            const int height = 60;
            var result = new Canvas
            {
                Width = width,
                Height = height,
                Background = background
            };

            var border = new Border
            {
                Height = height,
                Width = width,
                BorderThickness = new Thickness(2, 2, 2, 2),
                BorderBrush = Brushes.Black
            };

            var text = new TextBlock
            {
                FontSize = 12,
                Margin = new Thickness(5),
                Width = width - 10,
                Height = height - 10,
                TextWrapping = TextWrapping.WrapWithOverflow
            };

            var bold = new Bold();
            bold.Inlines.Add(title + ": ");
            text.Inlines.Add(bold);
            text.Inlines.Add(desc);

            result.Children.Add(border);
            result.Children.Add(text);

            return result;
        }


        public static void AnimatePaneBox(this IMain form, ContentControl destination, UIElementCollection source, Action<FrameworkElement, IEnumerable<WorkItem>> action, FrameworkElement parent, IEnumerable<WorkItem> itemsToDelselect)
        {
            // Create a NameScope for this page so that
            // Storyboards can be used.
            //NameScope.SetNameScope((DependencyObject)form, new NameScope());

            Canvas containerCanvas = new Canvas();

            int curInteration = 0;

            foreach (FrameworkElement element in source)
            {
                curInteration++;
                string iterationName = "iter" + curInteration + Guid.NewGuid().ToString().Replace("-","");

                GeneralTransform tranform;

                try
                {
                    // Try to get a transform object.  It may not be possible. 
                    // (ie if the source or dest is not docked then it will fail and we cannot animate.
                    tranform = element.TransformToVisual(destination);
                }
                catch (InvalidOperationException)
                {
                    return;
                }


                Point rootPoint = tranform.Transform(new Point(0, 0));

                Rect sourceRelativeRect = new Rect(rootPoint.X - (destination.ActualWidth / 2),
                    rootPoint.Y - (destination.ActualHeight / 2), element.ActualWidth, element.ActualHeight);

                RectangleGeometry myRectangleGeometry = new RectangleGeometry { Rect = new Rect(0, 0, 0, 0) };

                // Assign the geometry a name so that
                // it can be targeted by a Storyboard.
                form.WindowRegisterName(iterationName, myRectangleGeometry);

                Path myPath = new Path
                {
                    Fill = ((Canvas)element).Background,
                    StrokeThickness = 1,
                    Stroke = Brushes.Black,
                    Data = myRectangleGeometry
                };


                RectAnimation myRectAnimation = new RectAnimation
                {
                    Duration = TimeSpan.FromSeconds(1),
                    FillBehavior = FillBehavior.Stop,
                    AccelerationRatio = 1,
                    // Set the From and To properties of the animation.
                    From = sourceRelativeRect,
                    To = new Rect(0, 0, 0, 0)
                };

                // Set the animation to target the Rect property
                // of the object named "MyAnimatedRectangleGeometry."
                Storyboard.SetTargetName(myRectAnimation, iterationName);
                Storyboard.SetTargetProperty(myRectAnimation, new PropertyPath(RectangleGeometry.RectProperty));

                // Create a storyboard to apply the animation.
                Storyboard ellipseStoryboard = new Storyboard();
                ellipseStoryboard.Children.Add(myRectAnimation);
                containerCanvas.Children.Add(myPath);

                // Start the storyboard when the Path loads.
                myPath.Loaded += ((sender, e) => ellipseStoryboard.Begin((FrameworkElement)form));

                object currentContent = destination.Content;
                ellipseStoryboard.Completed += ((sender, e) => destination.Content = currentContent);
                ellipseStoryboard.Completed += ((sender, e) => action(parent, itemsToDelselect));
            }

            containerCanvas.Background = Brushes.Transparent;
            Panel.SetZIndex(containerCanvas, 999);

            destination.Content = containerCanvas;
        }

        

    }
}
